home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / TCPIN.C < prev    next >
C/C++ Source or Header  |  1997-09-06  |  27KB  |  921 lines

  1. /* Process incoming TCP segments. Page number references are to ARPA RFC-793,
  2.  * the TCP specification.
  3.  *
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  *
  6.  * Mods by PA0GRI (access control)
  7.  * Copyright 1992 Gerard J van der Grinten, PA0GRI
  8.  */
  9. #include "global.h"
  10. #include "timer.h"
  11. #include "mbuf.h"
  12. #include "netuser.h"
  13. #include "internet.h"
  14. #include "tcp.h"
  15. #include "icmp.h"
  16.  
  17. #if !defined(_lint)
  18. static char rcsid[] OPTIONAL = "$Id: tcpin.c,v 1.19 1997/09/07 00:31:16 root Exp root $";
  19. #endif
  20.  
  21. static void update (struct tcb * tcb, struct tcp * seg, int16 length);
  22. static void proc_syn (struct tcb * tcb, char tos, struct tcp * seg);
  23. static void add_reseq (struct tcb * tcb, char tos, struct tcp * seg,
  24.                    struct mbuf * bp, int16 length);
  25. static void get_reseq (struct tcb * tcb, char *tos, struct tcp * seq,
  26.                    struct mbuf ** bp, int16 * length);
  27. static int trim (struct tcb * tcb, struct tcp * seg, struct mbuf ** bpp,
  28.              int16 * length);
  29. static int in_window (struct tcb * tcb, int32 seq);
  30.  
  31.  
  32.  
  33. /* This function is called from IP with the IP header in machine byte order,
  34.  * along with a mbuf chain pointing to the TCP header.
  35.  */
  36. void
  37. tcp_input (iface, ip, bp, rxbroadcast)
  38. struct iface *iface;        /* Incoming interface (ignored) */
  39. struct mbuf *bp;        /* Data field, if any */
  40. struct ip *ip;            /* IP header */
  41. int rxbroadcast;        /* Incoming broadcast - discard if true */
  42. {
  43. struct tcb *ntcb;
  44. register struct tcb *tcb;    /* TCP Protocol control block */
  45. struct tcp seg;        /* Local copy of segment header */
  46. struct connection conn;    /* Local copy of addresses */
  47. struct pseudo_header ph;/* Pseudo-header for checksumming */
  48. int hdrlen;        /* Length of TCP header */
  49. int16 length;
  50.  
  51.     if (bp == NULLBUF)
  52.         return;
  53.  
  54.     tcpInSegs++;
  55.     if (rxbroadcast) {
  56.         /* Any TCP packet arriving as a broadcast is
  57.          * to be completely IGNORED!!
  58.          */
  59.         free_p (bp);
  60.         return;
  61.     }
  62.     length = ip->length - IPLEN - ip->optlen;
  63.     ph.source = ip->source;
  64.     ph.dest = ip->dest;
  65.     ph.protocol = ip->protocol;
  66.     ph.length = length;
  67.     if (cksum (&ph, bp, length) != 0) {
  68.         /* Checksum failed, ignore segment completely */
  69.         tcpInErrs++;
  70.         free_p (bp);
  71.         return;
  72.     }
  73.     /* Form local copy of TCP header in host byte order */
  74.     if ((hdrlen = ntohtcp (&seg, &bp)) < 0) {
  75.         /* TCP header is too small */
  76.         free_p (bp);
  77.         return;
  78.     }
  79.     length -= (int16) hdrlen;
  80.  
  81.     /* Fill in connection structure and find TCB */
  82.     conn.local.address = ip->dest;
  83.     conn.local.port = seg.dest;
  84.     conn.remote.address = ip->source;
  85.     conn.remote.port = seg.source;
  86.  
  87.     if ((tcb = lookup_tcb (&conn)) == NULLTCB) {
  88.         /* If memory low, reject it - WG7J */
  89.         /* If this segment doesn't carry a SYN, reject it */
  90.         if (!seg.flags.syn) {
  91.             free_p (bp);
  92.             reset (ip, &seg);
  93.             return;
  94.         }
  95. #ifdef  TCPACCESS
  96.         if (tcp_check (TCPaccess, ip->source, seg.dest) > 0) {
  97.             free_p (bp);
  98.             reset (ip, &seg);
  99.             return;
  100.         }
  101. #endif
  102.         /* See if there's a TCP_LISTEN on this socket with
  103.          * unspecified remote address and port
  104.          */
  105.         conn.remote.address = 0;
  106.         conn.remote.port = 0;
  107.         /* NOS currently always listens on unspecified addresses ! - WG7J */
  108.         conn.local.address = 0;
  109.         if ((tcb = lookup_tcb (&conn)) == NULLTCB) {
  110.             /* No LISTENs, so reject */
  111.             free_p (bp);
  112.             reset (ip, &seg);
  113.             return;
  114.         }
  115.         /* We've found an server listen socket, so clone the TCB */
  116.         if (tcb->flags.clone) {
  117.             ntcb = (struct tcb *) mallocw (sizeof (struct tcb));
  118.  
  119.             ASSIGN (*ntcb, *tcb);
  120.             tcb = ntcb;
  121.             tcb->timer.arg = tcb;
  122.             /* Put on list */
  123.             tcb->next = Tcbs;
  124.             Tcbs = tcb;
  125.         }
  126.         /* Put all the socket info into the TCB */
  127.         tcb->conn.local.address = ip->dest;
  128.         tcb->conn.remote.address = ip->source;
  129.         tcb->conn.remote.port = seg.source;
  130.  
  131.         /* Now point to the tcp interface specific parameters if
  132.          * none set. This is only needed for incoming connections.
  133.          * Outgoing ones get the pointer set in open_tcp() - WG7J
  134.          */
  135.         tcb->parms = iface->tcp;
  136.  
  137.         /* Find a known rtt or load interface default */
  138.         set_irtt (tcb);
  139.     }
  140.     tcb->flags.congest = ip->flags.congest;
  141.     /* Do unsynchronized-state processing (p. 65-68) */
  142.     switch (tcb->state) {
  143.         case TCP_CLOSED:
  144.             free_p (bp);
  145.             reset (ip, &seg);
  146.             return;
  147.         case TCP_LISTEN:
  148.             if (seg.flags.rst) {
  149.                 free_p (bp);
  150.                 return;
  151.             }
  152.             if (seg.flags.ack) {
  153.                 free_p (bp);
  154.                 reset (ip, &seg);
  155.                 return;
  156.             }
  157.             if (seg.flags.syn) {
  158.                 /* (Security check is bypassed) */
  159.                 /* page 66 */
  160.                 proc_syn (tcb, ip->tos, &seg);
  161.                 send_syn (tcb);
  162.                 setstate (tcb, TCP_SYN_RECEIVED);
  163. #if 0
  164.                 if (length != 0 || seg.flags.fin) {
  165.                     /* Continue processing if there's more */
  166.                     break;
  167.                 }
  168. #endif
  169.                 tcp_output (tcb);
  170.             }
  171.             free_p (bp);    /* Unlikely to get here directly */
  172.             return;
  173.         case TCP_SYN_SENT:
  174.             if (seg.flags.ack) {
  175.                 if (!seq_within (seg.ack, tcb->iss + 1, tcb->snd.nxt)) {
  176.                     free_p (bp);
  177.                     reset (ip, &seg);
  178.                     return;
  179.                 }
  180.             }
  181.             if (seg.flags.rst) {    /* p 67 */
  182.                 if (seg.flags.ack) {
  183.                     /* The ack must be acceptable since we just checked it.
  184.                      * This is how the remote side refuses connect requests.
  185.                      */
  186.                     close_self (tcb, RESET);
  187.                 }
  188.                 free_p (bp);
  189.                 return;
  190.             }
  191.             /* (Security check skipped here) */
  192.             /* Check incoming precedence; it must match if there's an ACK */
  193.             if (seg.flags.ack && PREC (ip->tos) != PREC (tcb->tos)) {    /*lint !e702 */
  194.                 free_p (bp);
  195.                 reset (ip, &seg);
  196.                 return;
  197.             }
  198.             if (seg.flags.syn) {
  199.                 proc_syn (tcb, ip->tos, &seg);
  200.                 if (seg.flags.ack) {
  201.                     /* Our SYN has been acked, otherwise the ACK
  202.                      * wouldn't have been valid.
  203.                      */
  204.                     update (tcb, &seg, length);
  205.                     setstate (tcb, TCP_ESTABLISHED);
  206.                 } else
  207.                     setstate (tcb, TCP_SYN_RECEIVED);
  208.  
  209.                 if (length != 0 || seg.flags.fin)
  210.                     break;    /* Continue processing if there's more */
  211.  
  212.                 tcp_output (tcb);
  213.             } else
  214.                 free_p (bp);    /* Ignore if neither SYN or RST is set */
  215.             return;
  216.         default:
  217.             break;
  218.     }
  219.     /* We reach this point directly in any synchronized state. Note that
  220.      * if we fell through from LISTEN or SYN_SENT processing because of a
  221.      * data-bearing SYN, window trimming and sequence testing "cannot fail".
  222.      */
  223.  
  224.     /* Trim segment to fit receive window. */
  225.     if (trim (tcb, &seg, &bp, &length) == -1) {
  226.         /* Segment is unacceptable */
  227.         if (!seg.flags.rst) {    /* NEVER answer RSTs */
  228.             /* In SYN_RECEIVED state, answer a retransmitted SYN
  229.              * with a retransmitted SYN/ACK.
  230.              */
  231.             if (tcb->state == TCP_SYN_RECEIVED)
  232.                 tcb->snd.ptr = tcb->snd.una;
  233.             tcb->flags.force = 1;
  234.             tcp_output (tcb);
  235.         }
  236.         return;
  237.     }
  238.     /* If segment isn't the next one expected, and there's data
  239.      * or flags associated with it, put it on the resequencing
  240.      * queue, ACK it and return.
  241.      *
  242.      * Processing the ACK in an out-of-sequence segment without
  243.      * flags or data should be safe, however.
  244.      */
  245.     if (seg.seq != tcb->rcv.nxt && (length != 0 || seg.flags.syn || seg.flags.fin)) {
  246.         add_reseq (tcb, ip->tos, &seg, bp, length);
  247.         tcb->flags.force = 1;
  248.         tcp_output (tcb);
  249.         return;
  250.     }
  251.     /* This loop first processes the current segment, and then
  252.      * repeats if it can process the resequencing queue.
  253.      */
  254.     for ( ; ; ) {
  255.         /* We reach this point with an acceptable segment; all data and flags
  256.          * are in the window, and the starting sequence number equals rcv.nxt
  257.          * (p. 70)
  258.          */
  259.         if (seg.flags.rst) {
  260.             if (tcb->state == TCP_SYN_RECEIVED
  261.                 && !tcb->flags.clone && !tcb->flags.active) {
  262.                 /* Go back to listen state only if this was
  263.                  * not a cloned or active server TCB
  264.                  */
  265.                 setstate (tcb, TCP_LISTEN);
  266.             } else
  267.                 close_self (tcb, RESET);
  268.             free_p (bp);
  269.             return;
  270.         }
  271.         /* (Security check skipped here) p. 71 */
  272.         /* Check for precedence mismatch or erroneous extra SYN */
  273.         if (PREC (ip->tos) != PREC (tcb->tos) || seg.flags.syn) {    /*lint !e702 */
  274.             free_p (bp);
  275.             reset (ip, &seg);
  276.             return;
  277.         }
  278.         /* Check ack field p. 72 */
  279.         if (!seg.flags.ack) {
  280.             free_p (bp);    /* All segments after synchronization must have ACK */
  281.             return;
  282.         }
  283.         /* Process ACK */
  284.         switch (tcb->state) {
  285.             case TCP_SYN_RECEIVED:
  286.                 if (seq_within (seg.ack, tcb->snd.una + 1, tcb->snd.nxt)) {
  287.                     update (tcb, &seg, length);
  288.                     setstate (tcb, TCP_ESTABLISHED);
  289.                 } else {
  290.                     free_p (bp);
  291.                     reset (ip, &seg);
  292.                     return;
  293.                 }
  294.                 break;
  295.             case TCP_ESTABLISHED:
  296.             case TCP_CLOSE_WAIT:
  297.                 update (tcb, &seg, length);
  298.                 break;
  299.             case TCP_FINWAIT1:    /* p. 73 */
  300.                 update (tcb, &seg, length);
  301.                 if (tcb->sndcnt == 0)     /* Our FIN is acknowledged */
  302.                     setstate (tcb, TCP_FINWAIT2);
  303.                 break;
  304.             case TCP_FINWAIT2:
  305.                 update (tcb, &seg, length);
  306.                 break;
  307.             case TCP_CLOSING:
  308.                 update (tcb, &seg, length);
  309.                 if (tcb->sndcnt == 0) {
  310.                     /* Our FIN is acknowledged */
  311.                     setstate (tcb, TCP_TIME_WAIT);
  312.                     set_timer (&tcb->timer, MSL2 * 1000L);
  313.                     start_timer (&tcb->timer);
  314.                 }
  315.                 break;
  316.             case TCP_LAST_ACK:
  317.                 update (tcb, &seg, length);
  318.                 if (tcb->sndcnt == 0) {
  319.                     /* Our FIN is acknowledged, close connection */
  320.                     close_self (tcb, NORMAL);
  321.                     return;
  322.                 }
  323.                 break;
  324.             case TCP_TIME_WAIT:
  325.                 start_timer (&tcb->timer);
  326.                 break;
  327.             default:
  328.                 break;
  329.         }
  330.  
  331.         /* (URGent bit processing skipped here) */
  332.  
  333.         /* Process the segment text, if any, beginning at rcv.nxt (p. 74) */
  334.         if (length != 0) {
  335.             switch (tcb->state) {
  336.                 case TCP_SYN_RECEIVED:
  337.                 case TCP_ESTABLISHED:
  338.                 case TCP_FINWAIT1:
  339.                 case TCP_FINWAIT2:
  340.                     /* Place on receive queue */
  341.                     append (&tcb->rcvq, bp);
  342.                     tcb->rcvcnt += length;
  343.                     tcb->rcv.nxt += length;
  344.                     tcb->rcv.wnd -= length;
  345.                     tcb->flags.force = 1;
  346.                     /* Notify user */
  347.                     if (tcb->r_upcall)
  348.                         (*tcb->r_upcall) (tcb, tcb->rcvcnt);
  349.                     break;
  350.                 default:
  351.                     /* Ignore segment text */
  352.                     free_p (bp);
  353.                     break;
  354.             }
  355.         }
  356.         /* process FIN bit (p 75) */
  357.         if (seg.flags.fin) {
  358.             tcb->flags.force = 1;    /* Always respond with an ACK */
  359.  
  360.             switch (tcb->state) {
  361.                 case TCP_SYN_RECEIVED:
  362.                 case TCP_ESTABLISHED:
  363.                     tcb->rcv.nxt++;
  364.                     setstate (tcb, TCP_CLOSE_WAIT);
  365.                     break;
  366.                 case TCP_FINWAIT1:
  367.                     tcb->rcv.nxt++;
  368.                     if (tcb->sndcnt == 0) {
  369.                         /* Our FIN has been acked; bypass TCP_CLOSING state */
  370.                         setstate (tcb, TCP_TIME_WAIT);
  371.                         set_timer (&tcb->timer, MSL2 * 1000L);
  372.                         start_timer (&tcb->timer);
  373.                     } else
  374.                         setstate (tcb, TCP_CLOSING);
  375.                     break;
  376.                 case TCP_FINWAIT2:
  377.                     tcb->rcv.nxt++;
  378.                     setstate (tcb, TCP_TIME_WAIT);
  379.                     set_timer (&tcb->timer, MSL2 * 1000L);
  380.                     start_timer (&tcb->timer);
  381.                     break;
  382.                 case TCP_TIME_WAIT:    /* p 76 */
  383.                     start_timer (&tcb->timer);
  384.                     break;
  385.                 case TCP_CLOSE_WAIT:
  386.                 case TCP_CLOSING:
  387.                 case TCP_LAST_ACK:
  388.                 default:
  389.                     break;    /* Ignore */
  390.             }
  391.             /* Call the client again so he can see EOF */
  392.             if (tcb->r_upcall)
  393.                 (*tcb->r_upcall) (tcb, tcb->rcvcnt);
  394.         }
  395.         /* Scan the resequencing queue, looking for a segment we can handle,
  396.          * and freeing all those that are now obsolete.
  397.          */
  398.         while (tcb->reseq != NULLRESEQ && seq_ge (tcb->rcv.nxt, tcb->reseq->seg.seq)) {
  399.             get_reseq (tcb, &ip->tos, &seg, &bp, &length);
  400.             if (trim (tcb, &seg, &bp, &length) == 0)
  401.                 goto gotone;
  402.             /* Segment is an old one; trim has freed it */
  403.         }
  404.         break;
  405. gotone:
  406.     }
  407.     tcp_output (tcb);    /* Send any necessary ack */
  408. }
  409.  
  410.  
  411.  
  412. /* Process an incoming ICMP response */
  413. void
  414. tcp_icmp (icsource, source, dest, type, code, bpp)
  415. uint32 icsource OPTIONAL;    /* Sender of ICMP message (not used) */
  416. uint32 source;            /* Original IP datagram source (i.e. us) */
  417. uint32 dest;            /* Original IP datagram dest (i.e., them) */
  418. char type, code;        /* ICMP error codes */
  419. struct mbuf **bpp;        /* First 8 bytes of TCP header */
  420. {
  421. struct tcp seg;
  422. struct connection conn;
  423. register struct tcb *tcb;
  424.  
  425.     /* Extract the socket info from the returned TCP header fragment
  426.      * Note that since this is a datagram we sent, the source fields
  427.      * refer to the local side.
  428.      */
  429.     (void) ntohtcp (&seg, bpp);
  430.     conn.local.port = seg.source;
  431.     conn.remote.port = seg.dest;
  432.     conn.local.address = source;
  433.     conn.remote.address = dest;
  434.     if ((tcb = lookup_tcb (&conn)) == NULLTCB)
  435.         return;        /* Unknown connection, ignore */
  436.  
  437.     /* Verify that the sequence number in the returned segment corresponds
  438.      * to something currently unacknowledged. If not, it can safely
  439.      * be ignored.
  440.      */
  441.     if (!seq_within (seg.seq, tcb->snd.una, tcb->snd.nxt))
  442.         return;
  443.  
  444.     /* Destination Unreachable and Time Exceeded messages never kill a
  445.      * connection; the info is merely saved for future reference.
  446.      */
  447.     switch (uchar (type)) {
  448.         case ICMP_DEST_UNREACH:
  449.         case ICMP_TIME_EXCEED:
  450.             tcb->type = type;
  451.             tcb->code = code;
  452.             break;
  453.         case ICMP_QUENCH:
  454.             /* Source quench; reduce slowstart threshold to half,
  455.              * current window and restart slowstart
  456.              */
  457.             tcb->ssthresh = tcb->cwind / 2;
  458.             tcb->ssthresh = max (tcb->ssthresh, tcb->mss);
  459.             /* Shrink congestion window to 1 packet */
  460.             tcb->cwind = tcb->mss;
  461.             break;
  462.         default:
  463.             break;
  464.     }
  465. }
  466.  
  467.  
  468.  
  469. /* Send an acceptable reset (RST) response for this segment
  470.  * The RST reply is composed in place on the input segment
  471.  */
  472. void
  473. reset (ip, seg)
  474. struct ip *ip;            /* Offending IP header */
  475. register struct tcp *seg;    /* Offending TCP header */
  476. {
  477. struct mbuf *hbp;
  478. struct pseudo_header ph;
  479. int16 tmp;
  480.  
  481.     if (seg->flags.rst)
  482.         return;        /* Never send an RST in response to an RST */
  483.  
  484.     /* Compose the RST IP pseudo-header, swapping addresses */
  485.     ph.source = ip->dest;
  486.     ph.dest = ip->source;
  487.     ph.protocol = TCP_PTCL;
  488.     ph.length = TCPLEN;
  489.  
  490.     /* Swap port numbers */
  491.     tmp = seg->source;
  492.     seg->source = seg->dest;
  493.     seg->dest = tmp;
  494.  
  495.     if (seg->flags.ack) {
  496.         /* This reset is being sent to clear a half-open connection.
  497.          * Set the sequence number of the RST to the incoming ACK
  498.          * so it will be acceptable.
  499.          */
  500.         seg->flags.ack = 0;
  501.         seg->seq = seg->ack;
  502.         seg->ack = 0;
  503.     } else {
  504.         /* We're rejecting a connect request (SYN) from TCP_LISTEN state
  505.          * so we have to "acknowledge" their SYN.
  506.          */
  507.         seg->flags.ack = 1;
  508.         seg->ack = seg->seq;
  509.         seg->seq = 0;
  510.         if (seg->flags.syn)
  511.             seg->ack++;
  512.     }
  513.     /* Set remaining parts of packet */
  514.     seg->flags.urg = 0;
  515.     seg->flags.psh = 0;
  516.     seg->flags.rst = 1;
  517.     seg->flags.syn = 0;
  518.     seg->flags.fin = 0;
  519.     seg->wnd = 0;
  520.     seg->up = 0;
  521.     seg->mss = 0;
  522.     seg->optlen = 0;
  523.     if ((hbp = htontcp (seg, NULLBUF, &ph)) == NULLBUF)
  524.         return;
  525.     /* Ship it out (note swap of addresses) */
  526.     (void) ip_send (ip->dest, ip->source, TCP_PTCL, ip->tos, 0, hbp, ph.length, 0, 0);
  527.     tcpOutRsts++;
  528. }
  529.  
  530.  
  531.  
  532. /* Process an incoming acknowledgement and window indication.
  533.  * From page 72.
  534.  */
  535. static void
  536. update (register struct tcb *tcb, register struct tcp *seg, int16 length)
  537. {
  538. int16 acked;
  539. int16 expand;
  540.  
  541.     acked = 0;
  542.     if (seq_gt (seg->ack, tcb->snd.nxt)) {
  543.         tcb->flags.force = 1;    /* Acks something not yet sent */
  544.         return;
  545.     }
  546.     /* Decide if we need to do a window update.
  547.      * This is always checked whenever a legal ACK is received,
  548.      * even if it doesn't actually acknowledge anything,
  549.      * because it might be a spontaneous window reopening.
  550.      */
  551.     if (seq_gt (seg->seq, tcb->snd.wl1) || ((seg->seq == tcb->snd.wl1)
  552.                       && seq_ge (seg->ack, tcb->snd.wl2))) {
  553.         /* If the window had been closed, crank back the
  554.          * send pointer so we'll immediately resume transmission.
  555.          * Otherwise we'd have to wait until the next probe.
  556.          */
  557.         if (tcb->snd.wnd == 0 && seg->wnd != 0)
  558.             tcb->snd.ptr = tcb->snd.una;
  559.         tcb->snd.wnd = seg->wnd;
  560.         tcb->snd.wl1 = seg->seq;
  561.         tcb->snd.wl2 = seg->ack;
  562.     }
  563.     /* See if anything new is being acknowledged */
  564.     if (!seq_gt (seg->ack, tcb->snd.una)) {
  565.         if (seg->ack != tcb->snd.una)
  566.             return;    /* Old ack, ignore */
  567.  
  568.         if (length != 0 || seg->flags.syn || seg->flags.fin)
  569.             return;    /* Nothing acked, but there is data */
  570.  
  571.         /* Van Jacobson "fast recovery" code */
  572.         if (++tcb->dupacks == TCPDUPACKS) {
  573.             /* We've had a burst of do-nothing acks, so
  574.              * we almost certainly lost a packet.
  575.              * Resend it now to avoid a timeout. (This is
  576.              * Van Jacobson's 'quick recovery' algorithm.)
  577.              */
  578.             int32 ptrsave;
  579.  
  580.             /* Knock the threshold down just as though
  581.              * this were a timeout, since we've had
  582.              * network congestion.
  583.              */
  584.             tcb->ssthresh = tcb->cwind / 2;
  585.             tcb->ssthresh = max (tcb->ssthresh, tcb->mss);
  586.  
  587.             /* Manipulate the machinery in tcp_output() to
  588.              * retransmit just the missing packet
  589.              */
  590.             ptrsave = tcb->snd.ptr;
  591.             tcb->snd.ptr = tcb->snd.una;
  592.             tcb->cwind = tcb->mss;
  593.             tcp_output (tcb);
  594.             tcb->snd.ptr = ptrsave;
  595.  
  596.             /* "Inflate" the congestion window, pretending as
  597.              * though the duplicate acks were normally acking
  598.              * the packets beyond the one that was lost.
  599.              */
  600.             tcb->cwind = (int16) (tcb->ssthresh + TCPDUPACKS * tcb->mss);
  601.         } else if (tcb->dupacks > TCPDUPACKS) {
  602.             /* Continue to inflate the congestion window
  603.              * until the acks finally get "unstuck".
  604.              */
  605.             tcb->cwind += tcb->mss;
  606.         }
  607.         return;
  608.     }
  609.     if (tcb->dupacks >= TCPDUPACKS && tcb->cwind > tcb->ssthresh) {
  610.         /* The acks have finally gotten "unstuck". So now we
  611.          * can "deflate" the congestion window, i.e. take it
  612.          * back down to where it would be after slow start
  613.          * finishes.
  614.          */
  615.         tcb->cwind = tcb->ssthresh;
  616.     }
  617.     tcb->dupacks = 0;
  618.  
  619.     /* We're here, so the ACK must have actually acked something */
  620.     acked = (int16) (seg->ack - tcb->snd.una);
  621.  
  622.     /* Expand congestion window if not already at limit and if
  623.      * this packet wasn't retransmitted
  624.      */
  625.     if (tcb->cwind < tcb->snd.wnd && !tcb->flags.retran) {
  626.         if (tcb->cwind < tcb->ssthresh) {
  627.             /* Still doing slow start/CUTE, expand by amount acked */
  628.             expand = min (acked, tcb->mss);
  629.         } else {
  630.             /* Steady-state test of extra path capacity */
  631.             expand = (int16) (((long) tcb->mss * tcb->mss) / tcb->cwind);
  632.         }
  633.         /* Guard against arithmetic overflow */
  634.         if (tcb->cwind + expand < tcb->cwind)
  635.             expand = MAXINT16 - tcb->cwind;
  636.  
  637.         /* Don't expand beyond the offered window */
  638.         if (tcb->cwind + expand > tcb->snd.wnd)
  639.             expand = tcb->snd.wnd - tcb->cwind;
  640.  
  641.         if (expand != 0) {
  642. #ifdef    notdef
  643.             /* Kick up the mean deviation estimate to prevent
  644.              * unnecessary retransmission should we already be
  645.              * bandwidth limited
  646.              */
  647.             tcb->mdev += ((long) tcb->srtt * expand) / tcb->cwind;
  648. #endif
  649.             tcb->cwind += expand;
  650.         }
  651.     }
  652.     /* Round trip time estimation */
  653.     if (tcb->flags.rtt_run && seq_ge (seg->ack, tcb->rttseq)) {
  654.         /* A timed sequence number has been acked */
  655.         tcb->flags.rtt_run = 0;
  656.         if (!(tcb->flags.retran)) {
  657.             int32 rtt;    /* measured round trip time */
  658.             int32 abserr;    /* abs(rtt - srtt) */
  659.  
  660.             /* This packet was sent only once and now
  661.              * it's been acked, so process the round trip time
  662.              */
  663.             rtt = msclock () - tcb->rtt_time;
  664.  
  665.             abserr = (rtt > tcb->srtt) ? rtt - tcb->srtt : tcb->srtt - rtt;
  666.             /* Run SRTT and MDEV integrators, with rounding */
  667.             tcb->srtt = ((AGAIN - 1) * tcb->srtt + rtt + (AGAIN / 2)) >> LAGAIN;        /*lint !e704 */
  668.             tcb->mdev = ((DGAIN - 1) * tcb->mdev + abserr + (DGAIN / 2)) >> LDGAIN;        /*lint !e704 */
  669.  
  670.             rtt_add (tcb->conn.remote.address, rtt);
  671.             /* Reset the backoff level */
  672.             tcb->backoff = 0;
  673.         }
  674.     }
  675.     tcb->sndcnt -= acked;    /* Update virtual byte count on snd queue */
  676.     tcb->snd.una = seg->ack;
  677.  
  678.     /* If we're waiting for an ack of our SYN, note it and adjust count */
  679.     if (!(tcb->flags.synack)) {
  680.         tcb->flags.synack = 1;
  681.         acked--;    /* One less byte to pull from real snd queue */
  682.     }
  683.     /* Remove acknowledged bytes from the send queue and update the
  684.      * unacknowledged pointer. If a FIN is being acked,
  685.      * pullup won't be able to remove it from the queue, but that
  686.      * causes no harm.
  687.      */
  688.     (void) pullup (&tcb->sndq, (unsigned char *)0, acked);
  689.  
  690.     /* Stop retransmission timer, but restart it if there is still
  691.      * unacknowledged data. If there is no more unacked data,
  692.      * the transmitter has gone at least momentarily idle, so
  693.      * record the time for the VJ restart-slowstart rule.
  694.      */
  695.     stop_timer (&tcb->timer);
  696.     if (tcb->snd.una != tcb->snd.nxt)
  697.         start_timer (&tcb->timer);
  698.     else
  699.         tcb->lastactive = msclock ();
  700.  
  701.     /* If retransmissions have been occurring, make sure the
  702.      * send pointer doesn't repeat ancient history
  703.      */
  704.     if (seq_lt (tcb->snd.ptr, tcb->snd.una))
  705.         tcb->snd.ptr = tcb->snd.una;
  706.  
  707.     /* Clear the retransmission flag since the oldest
  708.      * unacknowledged segment (the only one that is ever retransmitted)
  709.      * has now been acked.
  710.      */
  711.     tcb->flags.retran = 0;
  712.  
  713.     /* If outgoing data was acked, notify the user so he can send more
  714.      * unless we've already sent a FIN.
  715.      */
  716.     if (acked != 0 && tcb->t_upcall
  717.     && (tcb->state == TCP_ESTABLISHED || tcb->state == TCP_CLOSE_WAIT)) {
  718.         (*tcb->t_upcall) (tcb, tcb->window - tcb->sndcnt);
  719.     }
  720. }
  721.  
  722.  
  723.  
  724. /* Determine if the given sequence number is in our receiver window.
  725.  * NB: must not be used when window is closed!
  726.  */
  727. static
  728. int
  729. in_window (struct tcb *tcb, int32 seq)
  730. {
  731.     return seq_within (seq, tcb->rcv.nxt, (int32) (tcb->rcv.nxt + tcb->rcv.wnd - 1));
  732. }
  733.  
  734.  
  735.  
  736. /* Process an incoming SYN */
  737. static void
  738. proc_syn (register struct tcb *tcb, char tos, struct tcp *seg)
  739. {
  740. int16 mtu;
  741. struct tcp_rtt *tp;
  742. struct iftcp *parms = tcb->parms;
  743.  
  744.     tcb->flags.force = 1;    /* Always send a response */
  745.  
  746.     /* Note: It's not specified in RFC 793, but SND.WL1 and
  747.      * SND.WND are initialized here since it's possible for the
  748.      * window update routine in update() to fail depending on the
  749.      * IRS if they are left unitialized.
  750.      */
  751.     /* Check incoming precedence and increase if higher */
  752.     if (PREC (tos) > PREC (tcb->tos))        /*lint !e702 */
  753.         tcb->tos = tos;
  754.     tcb->rcv.nxt = seg->seq + 1;    /* p 68 */
  755.     tcb->snd.wl1 = tcb->irs = seg->seq;
  756.     tcb->snd.wnd = seg->wnd;
  757.     if (seg->mss != 0)
  758.         tcb->mss = seg->mss;
  759.     /* Check the MTU of the interface we'll use to reach this guy
  760.      * and lower the MSS so that unnecessary fragmentation won't occur
  761.      */
  762.     if ((mtu = ip_mtu (tcb->conn.remote.address)) != 0) {
  763.         /* Allow space for the TCP and IP headers */
  764.         mtu -= TCPLEN + IPLEN;
  765.         /* Find the minimum of the mss received, the mtu for the interface,
  766.          * AND the mss set for the interface ! - WG7J
  767.          */
  768.         mtu = min (mtu, parms->mss);
  769.         tcb->cwind = tcb->mss = min (mtu, tcb->mss);
  770.     }
  771.     /* Set the window size to the incoming interface value */
  772.     tcb->window = tcb->rcv.wnd = parms->window;
  773.  
  774.     /* See if there's round-trip time experience */
  775.     if ((tp = rtt_get (tcb->conn.remote.address)) != NULLRTT) {
  776.         tcb->srtt = tp->srtt;
  777.         tcb->mdev = tp->mdev;
  778.     } else
  779.         tcb->srtt = parms->irtt;
  780. }
  781.  
  782.  
  783.  
  784. /* Generate an initial sequence number and put a SYN on the send queue */
  785. void
  786. send_syn (register struct tcb *tcb)
  787. {
  788.     tcb->iss = geniss ();        /*lint !e703 */
  789.     tcb->rttseq = tcb->snd.wl2 = tcb->snd.una = tcb->iss;
  790.     tcb->snd.ptr = tcb->snd.nxt = tcb->rttseq;
  791.     tcb->sndcnt++;
  792.     tcb->flags.force = 1;
  793. }
  794.  
  795.  
  796.  
  797. /* Add an entry to the resequencing queue in the proper place */
  798. static void
  799. add_reseq (struct tcb *tcb, char tos, struct tcp *seg, struct mbuf *bp, int16 length)
  800. {
  801. register struct reseq *rp, *rp1;
  802.  
  803.     /* Allocate reassembly descriptor */
  804.     if ((rp = (struct reseq *) mallocw (sizeof (struct reseq))) == NULLRESEQ) {
  805.         /* No space, toss on floor */
  806.         free_p (bp);
  807.         return;
  808.     }
  809.     ASSIGN (rp->seg, *seg);
  810.     rp->tos = tos;
  811.     rp->bp = bp;
  812.     rp->length = length;
  813.  
  814.     /* Place on reassembly list sorting by starting seq number */
  815.     rp1 = tcb->reseq;
  816.     if (rp1 == NULLRESEQ || seq_lt (seg->seq, rp1->seg.seq)) {
  817.         /* Either the list is empty, or we're less than all other
  818.          * entries; insert at beginning.
  819.          */
  820.         rp->next = rp1;
  821.         tcb->reseq = rp;
  822.     } else {
  823.         /* Find the last entry less than us */
  824.         for (;;) {
  825.             if (rp1->next == NULLRESEQ || seq_lt (seg->seq, rp1->next->seg.seq)) {
  826.                 /* We belong just after this one */
  827.                 rp->next = rp1->next;
  828.                 rp1->next = rp;
  829.                 break;
  830.             }
  831.             rp1 = rp1->next;
  832.         }
  833.     }
  834. }
  835.  
  836.  
  837.  
  838. /* Fetch the first entry off the resequencing queue */
  839. static void
  840. get_reseq (register struct tcb *tcb, char *tos, struct tcp *seg, struct mbuf **bp, int16 *length)
  841. {
  842. register struct reseq *rp;
  843.  
  844.     if ((rp = tcb->reseq) == NULLRESEQ)
  845.         return;
  846.  
  847.     tcb->reseq = rp->next;
  848.  
  849.     *tos = rp->tos;
  850.     ASSIGN (*seg, rp->seg);
  851.     *bp = rp->bp;
  852.     *length = rp->length;
  853.     free ((char *) rp);
  854. }
  855.  
  856.  
  857.  
  858. /* Trim segment to fit window. Return 0 if OK, -1 if segment is
  859.  * unacceptable.
  860.  */
  861. static int
  862. trim (register struct tcb *tcb, register struct tcp *seg, struct mbuf **bpp, int16 *length)
  863. {
  864. long dupcnt, excess;
  865. int16 len;        /* Segment length including flags */
  866. char acceptit = 0;
  867.  
  868.     len = *length;
  869.     if (seg->flags.syn)
  870.         len++;
  871.     if (seg->flags.fin)
  872.         len++;
  873.  
  874.     /* Acceptability tests */
  875.     if (tcb->rcv.wnd == 0) {
  876.         /* Only in-order, zero-length segments are acceptable when
  877.          * our window is closed.
  878.          */
  879.         if (seg->seq == tcb->rcv.nxt && len == 0)
  880.             return 0;    /* Acceptable, no trimming needed */
  881.     } else {
  882.         /* Some part of the segment must be in the window */
  883.         if (in_window (tcb, seg->seq)) {
  884.             acceptit++;    /* Beginning is */
  885.         } else if (len != 0) {
  886.             if (in_window (tcb, (int32) (seg->seq + len - 1)) ||    /* End is */
  887.                 seq_within (tcb->rcv.nxt, seg->seq, (int32) (seg->seq + len - 1))) {    /* Straddles */
  888.                 acceptit++;
  889.             }
  890.         }
  891.     }
  892.     if (!acceptit) {
  893.         tcb->rerecv += len;    /* Assume all of it was a duplicate */
  894.         free_p (*bpp);
  895.         return -1;
  896.     }
  897.     if ((dupcnt = tcb->rcv.nxt - seg->seq) > 0) {
  898.         tcb->rerecv += dupcnt;
  899.         /* Trim off SYN if present */
  900.         if (seg->flags.syn) {
  901.             /* SYN is before first data byte */
  902.             seg->flags.syn = 0;
  903.             seg->seq++;
  904.             dupcnt--;
  905.         }
  906.         if (dupcnt > 0) {
  907.             (void) pullup (bpp, (unsigned char *)0, (int16) dupcnt);
  908.             seg->seq += dupcnt;
  909.             *length -= (int16) dupcnt;
  910.         }
  911.     }
  912.     if ((excess = seg->seq + *length - (tcb->rcv.nxt + tcb->rcv.wnd)) > 0) {
  913.         tcb->rerecv += excess;
  914.         /* Trim right edge */
  915.         *length -= (int16) excess;
  916.         trim_mbuf (bpp, *length);
  917.         seg->flags.fin = 0;    /* FIN follows last data byte */
  918.     }
  919.     return 0;
  920. }
  921.